﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Linq;
using System.Text;

namespace SmartMathLibrary.Management.Monitoring
{
    /// <summary>
    /// Occurs when the timer reached its interval.
    /// </summary>
    public delegate void HighPrecisionTimerTick(Object sender);

    /// <summary>
    /// This class represents a high precision timer, which works with ticks and not with miliseconds.
    /// </summary>
    [Serializable]
    public class HighPrecisionTimer
    {
        /// <summary>
        /// The interval of the timer.
        /// </summary>
        private long interval;

        /// <summary>
        /// The instance to measure the elapsed ticks.
        /// </summary>
        private readonly Stopwatch internalTimeMeasurement;

        /// <summary>
        /// The thread, in which the timer instance runs.
        /// </summary>
        private Thread workingThread;

        /// <summary>
        /// Occurs when the timer reached its interval.
        /// </summary>
        public event HighPrecisionTimerTick TimerTickEvent;

        /// <summary>
        /// Initializes a new instance of the <see cref="HighPrecisionTimer"/> class.
        /// </summary>
        /// <param name="interval">The interval of the timer.</param>
        public HighPrecisionTimer(long interval)
        {
            this.interval = interval;
            this.internalTimeMeasurement = new Stopwatch();
        }

        /// <summary>
        /// Gets or sets the interval of the timer.
        /// </summary>
        /// <value>The interval of the timer.</value>
        public long Interval
        {
            get { return interval; }
            set { interval = value; }
        }

        /// <summary>
        /// Starts the timer.
        /// </summary>
        public void Start()
        {
            this.workingThread = new Thread(new ThreadStart(this.InternalStart));
            this.workingThread.Start();
        }

        /// <summary>
        /// Stops the timer.
        /// </summary>
        public void Stop()
        {
            this.workingThread.Abort();
        }

        /// <summary>
        /// Internal method to manage the timer.
        /// </summary>
        private void InternalStart()
        {
            this.internalTimeMeasurement.Start();

            while (true)
            {
                if (this.internalTimeMeasurement.ElapsedTicks >= this.interval)
                {
                    this.TimerTickEvent(this);
                    this.internalTimeMeasurement.Reset();
                    this.internalTimeMeasurement.Start();
                }
            }
        }
    }
}